package pro.lepers.portfolio.controls {
	import flash.events.FocusEvent;
	import flash.display.InteractiveObject;
	import pro.lepers.portfolio.core.master;
	import pro.lepers.portfolio.event.MasterModelEvent;

	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;

	/**
	 * @author plepers
	 */
	public class KeyManager extends EventDispatcher {
		

		public function KeyManager( stage : InteractiveObject ) {
			if( instance != null ) throw new Error( "pro.lepers.portfolio.controls.KeyManagerClass est deja instancié" );
			_delayedEvents = new Vector.<Event>();
			stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
			
			stage.addEventListener( FocusEvent.FOCUS_OUT, stageFocusOut );
		}

		private function stageFocusOut (event : FocusEvent) : void {
			var stage : Stage = ( event.currentTarget as Stage );
			stage.focus = stage;
		}

		public function addKeyListener ( type : String, code : uint, listener : Function ) : void {
			addEventListener( type + code.toString(), listener );
		}

		public function removeKeyListener ( type : String, code : uint, listener : Function ) : void {
			removeEventListener( type + code.toString(), listener );
		}

		
		private function onKeyDown (event : KeyboardEvent) : void {
			var kEvent : String = event.type+event.keyCode.toString();
			if( ! hasEventListener( kEvent ) ) return;

			var evt : KeyboardEvent = new KeyboardEvent( kEvent );
			if( delayed( evt ) ) return;

			dispatchEvent( evt );
		}


		private function delayed (event : KeyboardEvent) : Boolean {
			if( master.globalScale < 1 ) {
				if( _delayedEvents.length == 0 ) 
					master.addEventListener( MasterModelEvent.SCALE_CHANGE, onScaleChange );
				_delayedEvents.push( event );
				master.upScale();
				return true;	
			}
			return false;
		}

		private function onScaleChange (event : MasterModelEvent) : void {
			if( master.globalScale == 1 ) {
				master.removeEventListener( MasterModelEvent.SCALE_CHANGE, onScaleChange );
				_flushStack();
			}
		}

		private function _flushStack () : void {
			var evt : Event;
			while( _delayedEvents.length > 0 ) {
				evt = _delayedEvents.shift();
				dispatchEvent( evt );
			}
		}

		
		private var _delayedEvents : Vector.<Event>;
		
		public static var instance : KeyManager;
		
		
		public static function start( stage : InteractiveObject  ) : KeyManager {
			if (instance == null)
				instance = new KeyManager( stage );
			return instance;
		}
		
	}
}
